import logging 
import sys
import thread 
import socket               # Import socket module
import notificationengine
import configmanager
import hashlib
import os
from lxml import etree
from lxml import objectify
from lxml import etree
import lxml
from StringIO import StringIO
import random

#import amazon_ses

log = logging.getLogger("notify")
L = []
class notificationengine:

  def execute(self, msg, params):
    if msg == None:
      s = "--"
    else:
      s = msg
    print "Would send msg if I were a concreate class " + msg.message
    return True

class EmailNotificationEngine (notificationengine):

  def __init__(self)  :
    pass

  def execute(self, msg, params):
#    try:
      #amazonSes = amazon_ses.AmazonSES(AWSAccessKeyId, AWSSecretKey)

      if 'subject' in params:
        subject = params['subject'].replace('%m', msg.message.text).replace("%c", msg.channel.text).replace("%s", msg.sender.text)
      else:
        subject = "You got Mail!"

      if 'body' in params:
        body = params['body'].replace('%m', msg.message.text).replace("%c", msg.channel.text).replace("%s", msg.sender.text)
      else:
        body = msg.message.text

      #emailmessage = amazon_ses.EmailMessage()
      #emailmessage.subject = unicode(subject, "UTF-8")
      #emailmessage.bodyText = body.encode("UTF-8")

      #amazonSes.sendEmail('Jag och mitt moln <admin@cloud.tigge.org>',
      #        params["address"], emailmessage    )
      log.debug("Subject: " + subject)
      log.debug("Body: " + body)
      return True
  
class andoidnotificationengine (notificationengine): 
    
#
#runing onece on setup when server start.
#
  def __init__(self):
    try:
        thread.start_new_thread(self.serverLisner, ())
    except Exception, errtxt:
        print errtxt
    pass
#
#
# 
  def initParser(self,schemaFile):
    if not os.path.exists(schemaFile):
        log.error("Could not find schema for messages. There should be a "
                "file named '"+schemaFile+"' in the script directory")
        sys.exit(1)
    messageSchema = etree.XMLSchema(file=open(schemaFile, "r"))
    return objectify.makeparser(schema = messageSchema)
#
# get Params from configen 
#Returns line params
  def getParams(self,user):
    confPath = os.path.expanduser("~"+user)+'/.irssi/irc2you_config.xml'
    log.info('confpath:'+confPath)
    confFile = open(confPath,"r")
    confString=""
    messageParser = self.initParser("resources/irc2you_config.xsd")
    while confFile:
      row= str(confFile.readline())
      confString += row
      s = row.split()
      n = len(s)
      if n == 0:
         break
    confFile.close()
    configxml = objectify.fromstring(confString, messageParser)
    return configxml.notifier.engine.param.text #.get("param"))
  
  #
  #parsar msg.
  #this one always in a thread.

  def parseMSG(self,c,addr):
      log.debug("starting thread...")
      boolforWhile=True
      rand=0
      char=c.recv(1024)
      if char=="":
          c.send("<error>stopSending emty msg to me :(</error>\n")
          c.close()
          return
      log.debug("from:"+str(addr)+"test:"+char)
      parser = etree.XMLParser(target = etree.TreeBuilder())
      result = etree.XML(char, parser)
      if len(result)> 0:
        user = result[0]
    
      if "auth" in result.tag:
        log.debug("trying to auth")
        rand = random.uniform(0, 9999999999999)
        msg="<nummber>"+str(rand)+"</nummber>"
        log.debug("sending nummer:"+msg)
        c.send(msg+"\n")
        log.debug("wating for stuff to do ")
        char=c.recv(1024)
        log.debug("from:"+str(addr)+"string:"+char)
        passnummber = self.getParams(user.text)
        log.info("passnummer"+passnummber)
        tobeHashstring = str(passnummber)+str(rand)
        log.info(tobeHashstring)#
        hashatpass=hashlib.sha1(tobeHashstring).hexdigest()
        log.info("hashat pass servern:  "+hashatpass)
        try:
            parser = etree.XMLParser(target = etree.TreeBuilder())
            result = etree.XML(char, parser)
            if len(result)>0 :
                authKey = result[0]
            else :
                authKey=""
                
            log.info("password:"+authKey.text)
            if authKey.text == hashatpass:
                log.info("you used the rigth password")
                if "hilight" == result.tag :
                    print "asking for hiligths"
                    sendString="<hilights>";
                    for item in range(len(L)):
                        ling=L.pop();
                        sendString += "<hilight>" + "<user>ettNamn</user><channel>" +  str(ling[1]) + "</channel><msg>" + str(ling[0])+ "</msg></hilight>"
                   
                    sendString += "</hilights>"
                    log.debug("return string: "+sendString+"\n")
                    c.send(sendString)
                    log.debug("after sending")
                    c.close()
                if "getChannel" == result.tag :
                    log.info("AndriodNotifier: asking for getChannel")
                    user = result[1]
                    log.debug(user.text)
                    channel = result[2]
                    log.debug(channel.text)
                              
                    if user is not None and channel is not None : 
                        conf = configmanager.configManager.getConfig(user.text)
                        conf.messageQueue.put(dict({'order':"getchanel",'channel':channel.text, 'conection':c ,'port':addr}))
                    
                elif "send" == result.tag:
                    
                    user = result[1]
                    log.debug(user.text)
                    channel = result[2]
                    log.debug(channel.text)
                    message = result[3]
                    log.debug(message.text)
                    if user is not "" and channel is not "" and message is not "": 
                        conf = configmanager.configManager.getConfig(user.text)
                        log.info("AndriodNotifier: sending message")
                        try:
                            conf.messageQueue.put(dict({'order':"send",'channel':channel.text, 'message':message.text}))
                        except Exception as e:
                           log.error("cant add on queue trying now")                     
                           conf.messageQueue.put(dict({'order':"send",'channel':channel.text, 'message':message.text}))
                        
                        c.send("Sending..."+message.text+" onchannel: "+channel.text)
                    else:
                         c.send("<error>saknar msg eller channel eller user</error>")
                    c.close()
                elif "getChannels" == result.tag:
                    log.info("AndriodNotifier: asking for getChannels")
                    user = result[1]
                    log.debug(user.text)
                    if user is not None : 
                        conf = configmanager.configManager.getConfig(user.text)
                        log.info("AndriodNotifier: sending message")
                        try:
                            conf.messageQueue.put(dict({'order':"getChanelList", 'conection':c ,'port':addr}))
                        except Exception as e:
                           log.error("cant add on queue trying now") 
                           conf.messageQueue.put(dict({'order':"getChanelList", 'conection':c ,'port':addr}))
                else:
                    c.send("<error>faild to parse tag:"+result.tag+"</error>")
                    log.info("cant parse top tag: "+result.tag)
            else :
               c.send("<error>you used the wrog password</error>")
               log.info("you used the wrong password")
               c.close()
        except Exception as e:
            print e
      elif "connect" in result.tag:
            nick = result[1]
            log.info("AndriodNotifier: conecting")
            rand = random.uniform(0, 9999999999999)
            c.send("<nummber>"+str(rand)+"</nummber>\n")
            conf = configmanager.configManager.getConfig(user.text)
            log.info("AndriodNotifier: conecting")
            try:
                conf.messageQueue.put(dict({'order':"send",'channel':nick.text, 'message':"Now you shood se the nummer:"+str(rand) +" on you phone if this is corect pleas answer yes else no"}))
            except Exception as e:
               log.error("cant add on queue trying now")
               conf.messageQueue.put(dict({'order':"send",'channel':nick.text, 'message':"Now you shood se the nummer:"+str(rand) +" on you phone if this is corect pleas answer yes else no"}))
    
            c.close()
      elif "getNick" in result.tag:
            log.debug("get nick")
            if user is not None :
                 conf = configmanager.configManager.getConfig(user.text)
                 log.info("AndriodNotifier: sending message")
                 conf.messageQueue.put(dict({'order':"getNick", 'conection':c ,'port':addr}))  
      else:
             c.send("error nead to auth yourself before")
             c.close()
      
    #
    #waiting for andriod client to connect.
    #
    #
  def serverLisner(self):
    running = 1
    serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    host = socket.gethostname() # Get local machine name
    port = 4567               # Reserve a port for your service.
    print 'starting server Onport ' + str(port)
    serversocket.bind(("0.0.0.0", port))        # Bind to the port
    serversocket.listen(5) 
    while running: 
        while True:
            c, addr = serversocket.accept()     # Establish connection with client.
            thread.start_new_thread(self.parseMSG, (c,addr))
            
        #c.close()
  def execute(self, msg, params):
    log.debug("appanding: "+msg.message)
    L.append([msg.message, msg.channel])
    #log.error("Tried to send android notification while the engine was not implemented")
    for item in L:
        print item
        print "shood send:" + msg.message + ".." + str(params)
    return True


class EchoNotificationEngine(notificationengine):
  def __init__(self):
    pass

  def execute(self, msg, params):
    if 'echoer' in params:
      conf = configmanager.configManager.getConfig(params['echoer'])
      if conf:
        if conf.messageQueue:
          log.info("EchoNotifier: sending message")
          conf.messageQueue.put(dict({'channel':msg.channel, 'message':msg.message.text}))
          return True
        else:
          return False
          log.error("EchoEngine could not find message queue for " + params['echoer'])
      else:
        return False
        log.error("EchoEngine could not find config for " + params['echoer'])
    else:
      log.error("EchoEngine is missing param: echoer")
      return False



class LogNotificationEngine(notificationengine):
  def __init__(self):
    pass

  def execute(self, msg, params):
    if params['body']:
      body = params['body'].replace('%m', str(msg.message)).replace("%c", str(msg.channel)).replace("%s", str(msg.sender))
    else:
      body = msg.message.text
    log.info("LogEngine -- Message:" + body)
    return True

emailEngine = EmailNotificationEngine()
androidEngine = andoidnotificationengine()
logEngine = LogNotificationEngine()
echoEngine = EchoNotificationEngine()

def get(engineName):
  if engineName == "email":
    return emailEngine
  elif engineName == "android":
    return androidEngine
  elif engineName == "log":
    return logEngine
  elif engineName == "echo":
    return echoEngine
  else:
    return None
